#include "Serial.h"

volatile char Serial_Class::RX_buf[256] = { 0 };	//接收数据的缓冲区

uint16_t Serial_Class::rx_cnt = 0;	//接收字节的计数
bool Serial_Class::rx_flag = false;	//接收数据是否完成

void Serial_Class::Init(uint32_t baudrate)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;
	uint16_t TIM_Arr = 0;	//定时器重装值（用于检测串口接收超时）

	TIM_Base_Class TIM_Uart = TIM_Base_Class(TIM14); //定时器14用于检测串口接收超时

	disable();	//关闭串口

	//配置定时器中断时间
	//定时器的时钟频率为系统时钟
	TIM_Arr = (uint16_t)(SystemCoreClock / (baudrate / 22) / 10 + 1);	//设置静默时间为22个位(定时器分频系数10)
	TIM_Uart.Init_Interrupt(TIM_Arr, 10);	//设置定时器的中断频率，用于设置串口接收超时检测

	//配置定时器中断
	NVIC_InitStructure.NVIC_IRQChannel = TIM14_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_InitStructure.NVIC_IRQChannelPriority = 1;
	NVIC_Init(&NVIC_InitStructure);

	//Usart1 NVIC 中断配置 配置
	NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_InitStructure.NVIC_IRQChannelPriority = 2;
	NVIC_Init(&NVIC_InitStructure);

	USART_InitStructure.USART_BaudRate = baudrate;
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;
	USART_InitStructure.USART_StopBits = USART_StopBits_1;
	USART_InitStructure.USART_Parity = USART_Parity_No;
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;

	Uart_Base_Class::Init(&USART_InitStructure);

	USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启接收中断

	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10;
	GPIO_Init(GPIOA, &GPIO_InitStructure);

	GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_1);
	GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_1);

	//测试用
	//Uart->CR2 |= 1 << 15;	//交换TX、RX引脚
	enable();	//使能串口

}

void Serial_Class::write(const char c)
{
	while (!((Uart->ISR)&USART_FLAG_TXE));		//发送数据寄存器空
	Uart->TDR = c;
}

void Serial_Class::write_RX(const char c)
{
	if (rx_cnt < 256)
	{
		RX_buf[rx_cnt] = c;
		rx_cnt++;
	}
}


//串口1		工作在发送接收模式，中断优先级2
void USART1_IRQHandler(void)
{
	if (USART1->ISR&(1 << 5))	//接受中断
	{
		TIM14->CNT = 0;	//计数器清0
		TIM14->CR1 |= TIM_CR1_CEN;	//使能定时器1
		Serial_Class::write_RX(USART1->RDR);
	}
}

//定时器14	用于串口Modbus检测，中断优先级1
void TIM14_IRQHandler(void)
{
	if (TIM14->SR&TIM_IT_Update)	//更新中断
	{
		TIM14->SR = ~TIM_IT_Update;
		TIM14->CR1 &= ~TIM_CR1_CEN;	//关闭定时器14
		Serial_Class::rx_flag = true;	//接收到了一帧数据
	}
}